using System.Collections.Generic;
using UnityEngine;

public class Pools : MonoBehaviour
{
	private static Pools m_Instance;

	private Dictionary<int, PoolBall> m_Balls;

	private Dictionary<int, PoolBall> m_CustomBalls;

	private PoolCue m_Cue;

	private Camera m_SceneCamera;

	private BallStorageRack m_BallStorageRack;

	private Sprite[] m_BallIcons;

	private List<PocketTrigger> m_PocketTriggers = new List<PocketTrigger>();

	[SerializeField]
	private Transform m_CueBallOrigin;

	[SerializeField]
	private Transform m_Black8Origin;

	[SerializeField]
	private Transform m_CenterOrigin;

	[SerializeField]
	private TableProfile m_Table;

	public static Pools Instance => m_Instance;

	public static Dictionary<int, PoolBall> Balls => m_Instance.m_Balls;

	public static Dictionary<int, PoolBall> CustomBalls => m_Instance.m_CustomBalls;

	public static PoolBall[] BallsArray => m_Instance._GetBallsArray();

	public static PoolBall[] CustomBallsArray => m_Instance._GetCustomBallArray();

	public static PoolCue Cue => m_Instance.m_Cue;

	public static WhiteBall CueBall => m_Instance.m_Balls[0] as WhiteBall;

	public static Camera SceneCamera => m_Instance.m_SceneCamera;

	public static BallStorageRack StorageRack => m_Instance.m_BallStorageRack;

	public static Sprite[] BallIcons => m_Instance.m_BallIcons;

	public static List<PocketTrigger> PocketTriggers => m_Instance.m_PocketTriggers;

	public static Transform CueBallOrigin => m_Instance.m_CueBallOrigin;

	public static Transform Black8Origin => m_Instance.m_Black8Origin;

	public static Transform CenterOrigin => m_Instance.m_CenterOrigin;

	public static TableProfile poolTable => m_Instance.m_Table;

	private void Awake()
	{
		if ((bool)m_Instance)
		{
			UnityEngine.Debug.LogError("There id two " + base.gameObject.name + " in the scene");
			UnityEngine.Debug.Break();
		}
		m_Instance = this;
		PoolBall[] array = UnityEngine.Object.FindObjectsOfType<PoolBall>();
		if (array != null)
		{
			m_Balls = new Dictionary<int, PoolBall>();
			int i = 0;
			for (int num = array.Length; i < num; i++)
			{
				m_Balls.Add(array[i].GetBallID(), array[i]);
			}
		}
		else
		{
			UnityEngine.Debug.LogError("the balls number is not explicit in the scene, please debug the code");
		}
		m_CustomBalls = new Dictionary<int, PoolBall>();
		PoolCue[] array2 = UnityEngine.Object.FindObjectsOfType<PoolCue>();
		if (array2 == null || array2.Length != 1)
		{
			UnityEngine.Debug.LogError("the number of the cue is not explicit in the scene, please debug the code");
		}
		else
		{
			m_Cue = array2[0];
		}
		m_SceneCamera = Camera.main;
		m_BallStorageRack = UnityEngine.Object.FindObjectOfType<BallStorageRack>();
		m_BallIcons = new Sprite[15];
		for (int j = 1; j <= 15; j++)
		{
			m_BallIcons[j - 1] = Resources.Load<Sprite>("BallsIcon/" + j);
		}
		m_PocketTriggers.AddRange(UnityEngine.Object.FindObjectsOfType<PocketTrigger>());
		m_PocketTriggers.Sort(delegate(PocketTrigger left, PocketTrigger right)
		{
			if (left.PocketIndex < right.PocketIndex)
			{
				return -1;
			}
			return (left.PocketIndex > right.PocketIndex) ? 1 : 0;
		});
	}

	private void _DisableStandardBalls()
	{
		for (int i = 1; i <= 15; i++)
		{
			m_Balls[i].gameObject.SetActive(value: false);
		}
	}

	private void _EnableStandardBalls()
	{
		for (int i = 1; i <= 15; i++)
		{
			m_Balls[i].gameObject.SetActive(value: true);
		}
	}

	private PoolBall[] _GetBallsArray()
	{
		PoolBall[] array = new PoolBall[m_Balls.Count];
		int i = 0;
		for (int num = array.Length; i < num; i++)
		{
			array[i] = m_Balls[i];
		}
		return array;
	}

	private PoolBall[] _GetCustomBallArray()
	{
		PoolBall[] array = new PoolBall[m_CustomBalls.Count];
		int num = 0;
		foreach (KeyValuePair<int, PoolBall> customBall in m_CustomBalls)
		{
			array[num++] = customBall.Value;
		}
		return array;
	}

	private void _AllBallsKinematic(bool cueBallKinematic)
	{
		for (int i = (!cueBallKinematic) ? 1 : 0; i <= 15; i++)
		{
			m_Balls[i].GetComponent<Rigidbody>().isKinematic = true;
		}
		foreach (KeyValuePair<int, PoolBall> customBall in m_CustomBalls)
		{
			customBall.Value.GetComponent<Rigidbody>().isKinematic = true;
		}
	}

	private void _AllBallsNonKinematic()
	{
		for (int i = 0; i <= 15; i++)
		{
			m_Balls[i].GetComponent<Rigidbody>().isKinematic = false;
		}
		foreach (KeyValuePair<int, PoolBall> customBall in m_CustomBalls)
		{
			customBall.Value.GetComponent<Rigidbody>().isKinematic = false;
		}
	}

	private List<PoolBall> _GetBalls(int min, int max)
	{
		min = Mathf.Max(0, min);
		max = Mathf.Min(15, max);
		List<PoolBall> list = new List<PoolBall>();
		for (int i = min; i <= max; i++)
		{
			if (m_Balls[i].BallState == PoolBall.State.IDLE)
			{
				list.Add(m_Balls[i]);
			}
		}
		return list;
	}

	public static List<PoolBall> GetSolidAndStripeBalls()
	{
		List<PoolBall> list = new List<PoolBall>();
		list.AddRange(GetSolidBalls());
		list.AddRange(GetStripeBalls());
		return list;
	}

	public static List<PoolBall> GetSolidBalls()
	{
		List<PoolBall> list = new List<PoolBall>();
		list.AddRange(m_Instance._GetBalls(1, 7));
		return list;
	}

	public static List<PoolBall> GetStripeBalls()
	{
		List<PoolBall> list = new List<PoolBall>();
		list.AddRange(m_Instance._GetBalls(9, 15));
		return list;
	}

	public static void AllBallsKinematic(bool cueBallKinematic = false)
	{
		m_Instance._AllBallsKinematic(cueBallKinematic);
	}

	public static void AllBallsNonKinematic()
	{
		m_Instance._AllBallsNonKinematic();
	}

	public static void ResetAllBalls(bool pottedOnly, bool black8Origin)
	{
		CheckAnyBallInTheResetBallArea();
		IDictionary<int, PoolBall> dictionary = new Dictionary<int, PoolBall>();
		int num = 0;
		float num2 = 1.732f;
		for (int i = 1; i <= 15; i++)
		{
			if (Balls[i].BallState != PoolBall.State.HIDE && ((pottedOnly && Balls[i].BallState == PoolBall.State.POTTED) || !pottedOnly))
			{
				dictionary.Add(i, Balls[i]);
			}
		}
		if (dictionary.Count == 0)
		{
			return;
		}
		if (black8Origin && dictionary.ContainsKey(8))
		{
			dictionary[8].Reset();
			SupportTools.SetPosition(dictionary[8].gameObject, Black8Origin.position, SupportTools.AxisIgnore.IgnoreY);
			num = 1;
			dictionary.Remove(8);
		}
		float num3 = 0.0001f;
		float num4 = (CueBall.GetRadius() + num3) * 2f;
		Vector3 position = Black8Origin.position;
		float num5 = position.x - num2 * num4;
		Vector3 one = Vector3.one;
		List<int> list = new List<int>(dictionary.Keys);
		int j = 1;
		int num6 = 1;
		for (; j <= 5; j++)
		{
			Vector3 position2 = Black8Origin.position;
			float num7 = position2.z - (float)(j - 1) * 0.5f * num4;
			int num8 = 1;
			while (num8 <= j && dictionary.Count != 0)
			{
				if (num6 == 5 && num == 1)
				{
					num7 += num4;
				}
				else
				{
					if (num6 > 15 - dictionary.Count - num)
					{
						int index = UnityEngine.Random.Range(0, dictionary.Count);
						int key = list[index];
						PoolBall poolBall = dictionary[key];
						poolBall.Reset();
						one.z = num7;
						one.x = num5;
						SupportTools.SetPosition(poolBall.gameObject, one, SupportTools.AxisIgnore.IgnoreY);
						dictionary.Remove(key);
						list.RemoveAt(index);
					}
					num7 += num4;
				}
				num8++;
				num6++;
			}
			num5 += 0.5f * num4 * num2;
		}
	}

	private static void CheckAnyBallInTheResetBallArea()
	{
		float radius = CueBall.GetRadius() * 7f;
		Collider[] array = Physics.OverlapSphere(Black8Origin.position, radius, (1 << LayerMask.NameToLayer("Ball")) | (1 << LayerMask.NameToLayer("WhiteBall")));
		Vector3 p = CenterOrigin.position;
		Vector3 p2 = CueBallOrigin.position;
		int i = 0;
		for (int num = array.Length; i < num; i++)
		{
			if (array[i].name.Contains("WhiteBall"))
			{
				PutBallToThePoint(array[i].GetComponent<WhiteBall>(), ref p2);
			}
			else
			{
				PutBallToThePoint(array[i].GetComponent<PoolBall>(), ref p);
			}
		}
	}

	public static void PutBallToThePoint(PoolBall ball, ref Vector3 p)
	{
		float num = ball.GetRadius() + 0.01f;
		while (Physics.OverlapSphere(p, num, (1 << LayerMask.NameToLayer("Ball")) | (1 << LayerMask.NameToLayer("WhiteBall"))).Length != 0)
		{
			p.x -= num;
		}
		SupportTools.SetPosition(ball.gameObject, p, SupportTools.AxisIgnore.IgnoreY, useRigibody: true);
		p.x -= num;
	}

	public static void DisableStandardBalls()
	{
		m_Instance._DisableStandardBalls();
	}

	public static void EnableStandardBalls()
	{
		m_Instance._EnableStandardBalls();
	}

	public static Vector2 GetTableSize()
	{
		Constraint component = CueBall.GetComponent<Constraint>();
		Vector3 max = component.max;
		float x = max.x;
		Vector3 min = component.min;
		float x2 = x - min.x;
		Vector3 max2 = component.max;
		float z = max2.z;
		Vector3 min2 = component.min;
		Vector2 result = new Vector2(x2, z - min2.z);
		return result;
	}

	public static void GetTableMinAndMaxPoints(out Vector3 min, out Vector3 max)
	{
		Constraint component = CueBall.GetComponent<Constraint>();
		min = component.min;
		Vector3 position = CueBall.transform.position;
		min.y = position.y;
		max = component.max;
		Vector3 position2 = CueBall.transform.position;
		max.y = position2.y;
	}
}
